package com.lnsoft.dqfs.server.handle;

import com.lnsoft.dqfs.server.handle.codec.Frame;
import com.lnsoft.dqfs.server.handle.codec.RespFrame;
import com.lnsoft.dqfs.server.handle.codec.ServiceFrame;
import com.lnsoft.dqfs.server.handle.codec.UploadServiceFrame;
import com.lnsoft.dqfs.server.handle.threadpools.ServiceInvokePools;
import com.lnsoft.dqfs.server.util.Arrays16;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class DqfsChannelHandle extends ChannelInboundHandlerAdapter {

    //private static final CacheClient cache = CacheClient.getInstance();

    private Frame frame;
    private ServiceInvokePools invokePools;

    public DqfsChannelHandle(Frame frame, ServiceInvokePools invokePools){
        this.frame = frame;
        this.invokePools = invokePools;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //log.debug("接收到客户端请求{}", msg);
       try {
            RespFrame sendframe = (RespFrame) msg;
            byte[] resp = sendframe.getResp();
            if(resp != null) {
                // 不为空可以立即返回
                ctx.channel().writeAndFlush(sendframe.getResp());

                log.debug("客户端{}:{},主站向终端返回确认报文：{}", frame.getClientName(), frame.getServerPort(), Arrays16.toString(sendframe.getResp()));

            }
            final ServiceFrame serviceFrame = sendframe.getServiceFrame();
            if (serviceFrame != null) {
                // 交由自定义线程池处理
                invokePools.execute(ctx,serviceFrame,frame);
            }
       }finally {
           ReferenceCountUtil.release(msg);
       }
    }


    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        log.warn("客户端{}:{},断开执行清理工作",frame.getClientName(),frame.getServerPort());
        //cache.remove(frame.getClientId());
        clearFrame(ctx);
    }


    private void clearFrame(ChannelHandlerContext ctx) throws Exception{
        channelRead(ctx, RespFrame.builder().serviceFrame(UploadServiceFrame.builder().releaseFlag(true).build()).build());

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("客户端{}:{}handle error:{}", frame.getClientName(),frame.getServerPort(),cause);
        clearFrame(ctx);
        ctx.close();
    }
}
